package com.wonders.module.auth.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wonders.common.constant.CommonConstant;
import com.wonders.common.constant.TipConstant;
import com.wonders.framework.exception.BusinessException;
import com.wonders.framework.util.ValidateUtil;
import com.wonders.framework.util.bean.BeanUtil;
import com.wonders.module.auth.constant.AuthConstant;
import com.wonders.module.auth.dao.MenuDao;
import com.wonders.module.auth.dao.RoleAuthDao;
import com.wonders.module.auth.entity.bo.Menu;
import com.wonders.module.auth.entity.vo.MenuVo;
import com.wonders.module.auth.service.MenuService;

/**
 * 菜单业务层实现
 * 
 * @author WuBin
 * 
 */
@Service
public class MenuServiceImpl implements MenuService {

	@Autowired
	private MenuDao menuDao;

	@Autowired
	private RoleAuthDao roleAuthDao;

	public List<MenuVo> query(MenuVo menuVo) {
		List<MenuVo> menuList = BeanUtil.copyList(menuDao.query(menuVo),
				MenuVo.class);
		if (menuVo.getExcludeId() != null) {
			List<MenuVo> excludeMenuList = new ArrayList<MenuVo>();
			for (MenuVo menu : menuList) {
				if (menuVo.getExcludeId().equals(menu.getId())) {
					excludeMenuList.add(menu);
				}
			}
			filterListById(menuList, menuVo.getExcludeId(), excludeMenuList);
			menuList.removeAll(excludeMenuList);
		}
		return menuList;
	}

	/**
	 * 过滤菜单信息
	 * 
	 * @param menuList
	 *            菜单信息
	 * @param excludeId
	 *            排除的菜单编号
	 * @param excludeMenuList
	 *            排除的菜单信息
	 */
	private void filterListById(List<MenuVo> menuList, Long excludeId,
			List<MenuVo> excludeMenuList) {
		for (MenuVo menu : menuList) {
			if (excludeId.equals(menu.getParentId())) {
				excludeMenuList.add(menu);
				filterListById(menuList, menu.getId(), excludeMenuList);
			}
		}
	}

	public void save(MenuVo menuVo) {
		validate(menuVo, CommonConstant.Action.ADD);
		Menu menu = BeanUtil.copyProperties(menuVo, Menu.class);
		menu.setEnable(CommonConstant.Status.ENABLED);
		menuDao.save(menu);
	}

	public MenuVo load(Long id) {
		Menu menu = menuDao.get(Menu.class, id);
		if (menu == null) {
			throw new BusinessException(TipConstant.DATA.NOT_FOUND);
		}
		return BeanUtil.copyProperties(menu, MenuVo.class);
	}

	public void update(MenuVo menuVo) {
		validate(menuVo, CommonConstant.Action.EDIT);
		Menu menu = menuDao.get(Menu.class, menuVo.getId());
		if (menu == null) {
			throw new BusinessException(TipConstant.DATA.NOT_FOUND);
		}
		BeanUtil.copyProperties(menuVo, menu, "enable");
		menuDao.update(menu);
	}

	public void remove(Long id) {
		MenuVo menuVo = new MenuVo();
		menuVo.setParentId(id);
		menuVo.setEnable(CommonConstant.Status.ENABLED);
		List<Menu> list = menuDao.query(menuVo);
		if (list != null && list.size() > 0) {
			for (Menu menu : list) {
				remove(menu.getId());
			}
		}
		menuDao.remove(id);
		roleAuthDao.removeByAuth(id, AuthConstant.AuthType.MENU);
	}

	public void validate(MenuVo menuVo, String action) {
		if (!ValidateUtil.nullCheck(menuVo, "name")) {
			throw new BusinessException(TipConstant.PARAM.MISSING);
		}
		if (CommonConstant.Action.EDIT.equals(action)
				&& !ValidateUtil.nullCheck(menuVo, "id")) {
			throw new BusinessException(TipConstant.PARAM.MISSING);
		}
		if (!ValidateUtil.maxLengthCheck(menuVo.getName(), 15)) {
			throw new BusinessException("名称" + TipConstant.PARAM.FORMAT_ERROR);
		}
		if (ValidateUtil.nullCheck(menuVo, "parentId")
				&& (!ValidateUtil.isNumber(menuVo.getParentId()) || !ValidateUtil
						.maxLengthCheck(menuVo.getParentId(), 19))) {
			throw new BusinessException("父级菜单" + TipConstant.PARAM.FORMAT_ERROR);
		}
		if (ValidateUtil.nullCheck(menuVo, "url")
				&& !ValidateUtil.maxLengthCheck(menuVo.getUrl(), 50)) {
			throw new BusinessException("链接" + TipConstant.PARAM.FORMAT_ERROR);
		}
		if (ValidateUtil.nullCheck(menuVo, "enable")
				&& (!ValidateUtil.isNumber(menuVo.getEnable()) || !ValidateUtil
						.maxLengthCheck(menuVo.getEnable(), 3))) {
			throw new BusinessException("排序" + TipConstant.PARAM.FORMAT_ERROR);
		}
	}

}
